import os

import win32gui, win32con, win32ui
import re, traceback
from ctypes import windll
import pyautogui as pag
from PIL import ImageGrab

from basic.logger import logger


class cWindow:
    def __init__(self):
        self._hwnd = None

    def SetAsForegroundWindow(self):
        # First, make sure all (other) always-on-top windows are hidden.
        self.hide_always_on_top_windows()
        win32gui.SetForegroundWindow(self._hwnd)

    def Maximize(self):
        win32gui.ShowWindow(self._hwnd, win32con.SW_MAXIMIZE)

    def _window_enum_callback(self, hwnd, regex):
        '''Pass to win32gui.EnumWindows() to check all open windows'''
        if self._hwnd is None and re.match(regex, str(win32gui.GetWindowText(hwnd))) is not None:
            self._hwnd = hwnd

    def find_window_regex(self, regex):
        self._hwnd = None
        win32gui.EnumWindows(self._window_enum_callback, regex)

    def hide_always_on_top_windows(self):
        win32gui.EnumWindows(self._window_enum_callback_hide, None)

    def _window_enum_callback_hide(self, hwnd, unused):
        if hwnd != self._hwnd:  # ignore self
            # Is the window visible and marked as an always-on-top (topmost) window?
            if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowLong(hwnd,
                                                                         win32con.GWL_EXSTYLE) & win32con.WS_EX_TOPMOST:
                # Ignore windows of class 'Button' (the Start button overlay) and
                # 'Shell_TrayWnd' (the Task Bar).
                className = win32gui.GetClassName(hwnd)
                if not (className == 'Button' or className == 'Shell_TrayWnd' or className == 'Shell_SecondaryTrayWnd'):
                    # Force-minimize the window.
                    # Fortunately, this seems to work even with windows that
                    # have no Minimize button.
                    # Note that if we tried to hide the window with SW_HIDE,
                    # it would disappear from the Task Bar as well.
                    win32gui.ShowWindow(hwnd, win32con.SW_FORCEMINIMIZE)

    def grab_picture(self):
        # 获取句柄窗口的大小信息
        left, top, right, bot = win32gui.GetWindowRect(self._hwnd)
        width = right - left
        height = bot - top
        # 返回句柄窗口的设备环境，覆盖整个窗口，包括非客户区，标题栏，菜单，边框
        hWndDC = win32gui.GetWindowDC(self._hwnd)
        # 创建设备描述表
        mfcDC = win32ui.CreateDCFromHandle(hWndDC)
        # 创建内存设备描述表
        saveDC = mfcDC.CreateCompatibleDC()
        # 创建位图对象准备保存图片
        saveBitMap = win32ui.CreateBitmap()
        # 为bitmap开辟存储空间
        saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
        # 将截图保存到saveBitMap中
        saveDC.SelectObject(saveBitMap)
        # 保存bitmap到内存设备描述表
        saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)

        # 如果要截图到打印设备：
        ###最后一个int参数：0-保存整个窗口，1-只保存客户区。如果PrintWindow成功函数返回值为1
        result = windll.user32.PrintWindow(self._hwnd, saveDC.GetSafeHdc(), 0)
        # print(result)  # PrintWindow成功则输出1

        # 保存图像
        ##方法一：windows api保存
        ###保存bitmap到文件
        if os.path.exists("temp.png"):
            os.remove("temp.png")
        saveBitMap.SaveBitmapFile(saveDC, "temp.png")
        return (left, top)

    # 基于坐标的截屏
    def screen_part_shot(self,startX, startY, width, height):
        """屏幕截图"""
        # 1、用grab函数截图，参数为左上角和右下角左标
        left, top, right, bot = win32gui.GetWindowRect(self._hwnd)
        im = ImageGrab.grab((left + startX, top + startY, width, height))
        # im = ImageGrab.grab()
        if os.path.exists("temp.png"):
            os.remove("temp.png")
        else:
            logger.info("要删除的文件不存在！")
        im.save('temp.png')
        return (left, top)

    """ 获取鼠标的坐标位置 """
    def where_is_mouse(self):
        try:
            ptx, pty = pag.position()  # 获取当前鼠标的位置
            showStr = "Position:" + str(ptx).rjust(4) + ',' + str(pty).rjust(4)
            print(showStr)
        except KeyboardInterrupt:
            print('end....')

# 获取所有系统中的窗口句柄
def _MyCallback(hwnd, extra):
    windows = extra
    temp = []
    temp.append(hex(hwnd))
    temp.append(win32gui.GetClassName(hwnd))
    temp.append(win32gui.GetWindowText(hwnd))
    windows[hwnd] = temp


if __name__ == "__main__":
    try:
        regex = "火影忍者Online"
        cW = cWindow()
        windows = {}
        win32gui.EnumWindows(_MyCallback, windows)
        # 查找窗口，返回句柄
        cW.find_window_regex(regex)
        cW.Maximize()
        cW.SetAsForegroundWindow()
        cW.grab_picture()
    except:
        f = open("log.txt", "w")
        f.write(traceback.format_exc())
        print(traceback.format_exc())
